package test.yzx.pproject;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.animation.Interpolator;

import java.util.ArrayList;

public class ViewAnimatorUtil {

    public interface ValueCallback{
        void onUpdate(Animator animation,float value);
        void onComplete(Animator animation);
        void onCancel(Animator animation);
        void onRepeat(Animator animation);
        void onStart(Animator animation);
    }
    public static class SimpleValueCallback implements ValueCallback{
        public void onStart(Animator animation){}
        public void onRepeat(Animator animation) {}
        public void onCancel(Animator animation) {}
        public void onUpdate(Animator animation, float value) {}
        public void onComplete(Animator animation) {}
    }
    public interface StatusChangedListener{
        void onStart();
        void onEnd();
    }
    public static class SimpleStatusChangedListener implements StatusChangedListener {
        public void onStart() {}
        public void onEnd() {}
    }
    public static class SimpleAnimatorListener implements Animator.AnimatorListener{
        public void onAnimationStart(Animator animation) {}
        public void onAnimationEnd(Animator animation) {}
        public void onAnimationCancel(Animator animation) {}
        public void onAnimationRepeat(Animator animation) {}
    }




    public static class BoundsChangeParam{
        public Float translateX;
        public Float translateY;
        public Float scaleX;
        public Float scaleY;
        public Float rotateX;
        public Float rotateY;
        public Float rotateZ;
        public Float alpha;

        public int duration = 300;//default 300
        public int delay = 0;
        public Interpolator interpolator;
    }


    /****** */
    public static Animator make(int duration, int delay, Interpolator interpolator, final ValueCallback callback, float... values){
        ValueAnimator anim = ValueAnimator.ofFloat(values).setDuration(duration);
        anim.setStartDelay(delay);
        if(interpolator != null)  anim.setInterpolator(interpolator);
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                callback.onUpdate(animation, (float) animation.getAnimatedValue());
            }
        });
        anim.addListener(new Animator.AnimatorListener() {
            public void onAnimationStart(Animator animation) {callback.onStart(animation);}
            public void onAnimationEnd(Animator animation) {callback.onComplete(animation);}
            public void onAnimationCancel(Animator animation) {callback.onCancel(animation);}
            public void onAnimationRepeat(Animator animation) {callback.onRepeat(animation);}
        });
        return anim;
    }

    /****** */
    public static void goBoundsTogether(final View target, BoundsChangeParam params, final StatusChangedListener callback){
        /// start make properties ///
        ArrayList<PropertyValuesHolder> holderList = new ArrayList<>(8);
        if(params.translateX != null)
            holderList.add(PropertyValuesHolder.ofFloat("translationX", target.getTranslationX(), params.translateX));
        if(params.translateY != null)
            holderList.add(PropertyValuesHolder.ofFloat("translationY", target.getTranslationY(), params.translateY));
        if(params.scaleX != null)
            holderList.add(PropertyValuesHolder.ofFloat("scaleX", target.getScaleX(), params.scaleX));
        if(params.scaleY != null)
            holderList.add(PropertyValuesHolder.ofFloat("scaleY", target.getScaleY(), params.scaleY));
        if(params.rotateX != null)
            holderList.add(PropertyValuesHolder.ofFloat("rotationX", target.getRotationX(), params.rotateX));
        if(params.rotateY != null)
            holderList.add(PropertyValuesHolder.ofFloat("rotationY", target.getRotationY(), params.rotateY));
        if(params.rotateZ != null)
            holderList.add(PropertyValuesHolder.ofFloat("rotation", target.getRotation(), params.rotateZ));
        if(params.alpha != null)
            holderList.add(PropertyValuesHolder.ofFloat("alpha", target.getAlpha(), params.alpha));
        if(holderList.isEmpty())
            throw new IllegalStateException("no properties to change !");
        /// start make animator ///
        ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(target, holderList.toArray(new PropertyValuesHolder[holderList.size()]));
        anim.setDuration(params.duration).setStartDelay(params.delay);
        if(params.interpolator != null)
            anim.setInterpolator(params.interpolator);
        if(callback != null)
            anim.addListener(new SimpleAnimatorListener(){
                public void onAnimationStart(Animator animation) {callback.onStart();}
                public void onAnimationEnd(Animator animation) {callback.onEnd();}
            });
        anim.start();
    }


    public static float calculateRange(float constractMaxDistance, float constractNowDistance, float resultMaxDistance){
        return constractNowDistance * resultMaxDistance / constractMaxDistance;
    }

    /** 重置各种变换属性 */
    public static void resetTransform(View v){
        ViewCompat.setAlpha(v, 1);
        ViewCompat.setScaleY(v, 1);
        ViewCompat.setScaleX(v, 1);
        ViewCompat.setTranslationY(v, 0);
        ViewCompat.setTranslationX(v, 0);
        ViewCompat.setRotation(v, 0);
        ViewCompat.setRotationY(v, 0);
        ViewCompat.setRotationX(v, 0);
        ViewCompat.setPivotY(v, v.getMeasuredHeight() / 2);
        ViewCompat.setPivotX(v, v.getMeasuredWidth() / 2);
    }

}
